package services

import (
	"context"
	"fmt"
	"io"
	"mime/multipart"
	"os"
	"path"
	"strings"

	"github.com/google/uuid"
	"github.com/volcengine/ve-tos-golang-sdk/v2/tos"

	"zwai-app/config"
)

// UploadImage 从前端接收文件流，保存到临时文件后调用 PutObjectFromFile 上传到 TOS
// 设置 ContentType 与公共读 ACL，确保浏览器能预览
func UploadImage(ctx context.Context, file multipart.File, header *multipart.FileHeader) (string, error) {
	cfg := config.Load()

	// 1) 写入临时文件
	ext := path.Ext(header.Filename)
	tmpPath := path.Join(os.TempDir(), uuid.New().String()+ext)
	tmpFile, err := os.Create(tmpPath)
	if err != nil {
		return "", fmt.Errorf("创建临时文件失败: %w", err)
	}
	defer func() {
		tmpFile.Close()
		os.Remove(tmpPath)
	}()

	if _, err := io.Copy(tmpFile, file); err != nil {
		return "", fmt.Errorf("保存临时文件失败: %w", err)
	}

	// 2) 初始化 TOS 客户端
	client, err := tos.NewClientV2(
		cfg.TOSEndpoint,
		tos.WithRegion(cfg.TOSRegion),
		tos.WithCredentials(tos.NewStaticCredentials(cfg.AccessKeyID, cfg.SecretAccessKey)),
	)
	if err != nil {
		return "", fmt.Errorf("初始化存储客户端失败: %w", err)
	}
	defer client.Close()

	// 3) 构造 PutObjectFromFileInput，含 ACL 和 ContentType
	key := fmt.Sprintf("images/%s%s", uuid.New().String(), ext)

	input := &tos.PutObjectFromFileInput{
		PutObjectBasicInput: tos.PutObjectBasicInput{
			Bucket: cfg.TOSBucket,
			Key:    key,
		},
		FilePath: tmpPath,
	}

	output, err := client.PutObjectFromFile(ctx, input)
	if err != nil {
		var msg string
		if se, ok := err.(*tos.TosServerError); ok {
			msg = fmt.Sprintf("服务端错误: code=%s, msg=%s", se.Code, se.Message)
		} else if ce, ok := err.(*tos.TosClientError); ok {
			msg = fmt.Sprintf("客户端错误: %s", ce.Cause)
		} else {
			msg = err.Error()
		}
		return "", fmt.Errorf("上传失败: %s", msg)
	}

	// 4) 拼接可访问 URL
	host := strings.TrimPrefix(cfg.TOSEndpoint, "https://")
	host = strings.TrimPrefix(host, "http://")
	url := fmt.Sprintf("https://%s.%s/%s", cfg.TOSBucket, host, key)

	fmt.Println("TOS RequestID:", output.RequestID)
	return url, nil
}
